#include <stdio.h>
#include <string.h>
#include <unistd.h>
 
#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_errno.h"
#include "iot_uart.h"
#include "hi_uart.h"
#include "hi_io.h"
#include "hi_gpio.h"
#include "hi_spi.h"

#define RED_INDEX   0
#define GREEN_INDEX 1
#define BLUE_INDEX  2
 
#define  WS2812_8x8_SPI0 0
#define  WS2812_LIGTH_LINE_SPI1 1
#define LEDCNT 35
int keep_going = 1;
int new_status = 0;
typedef struct ws
{
    unsigned char green;
    unsigned char red;
    unsigned char blue;
}ws_t;



//色带
unsigned char color[8][3]=
{
    {255,255,255},//白
    {255,255, 0 },
    {255, 0 ,255},
    { 0 ,255,255},
    { 0 , 0 ,255},//蓝
    { 0 ,255, 0 },//绿
    {255, 0 , 0 },//红
    { 0 , 0 , 0 }
};

/*--  调入了一幅图像：这是您新建的图像  --*/
/*--  宽度x高度=8x8  --*/
unsigned char love_heart[] = 
{
    0x00,0x24,0x3C,0x7E,0x7E,0x3C,0x18,0x00
};

unsigned char X_pic[] = 
{
    /*--  调入了一幅图像：C:\Users\zltro\Desktop\nowifi.bmp  --*/
    /*--  宽度x高度=8x8  --*/
    0x00,0x42,0x24,0x18,0x18,0x24,0x42,0x00
};

unsigned char R_pic[] = 
{
    /*--  调入了一幅图像：C:\Users\zltro\Desktop\nowifi.bmp  --*/
    /*--  宽度x高度=8x8  --*/
    0x80,0x40,0xA0,0x51,0x2A,0x15,0x0A,0x04
};
/*--  调入了一幅图像：C:\Users\zltro\Desktop\spark_dot.bmp  --*/
/*--  宽度x高度=48x8  --*/
/*--  横向取模，字节倒序  --*/
unsigned char spark_pic[] = 
{
    0x3C,0x3F,0x18,0x7E,0xBC,0x03,0x66,0x66,0x18,0xCC,0x98,0x01,0x0E,0x66,0x34,0xCC,
    0xD8,0x00,0x1C,0x3E,0x34,0x7C,0xF8,0x00,0x78,0x06,0x3C,0xCC,0x98,0x01,0x62,0x06,
    0x66,0xCC,0x98,0x01,0x66,0x06,0x66,0xCC,0x19,0x03,0x3C,0x0F,0xF7,0x9E,0x3D,0x07
};


unsigned char start_pic[] = 
{
/*--  调入了一幅图像：C:\Users\zltro\Desktop\start_pic.bmp  --*/
/*--  宽度x高度=48x8  --*/
0x3C,0x3F,0x0C,0x3F,0x7E,0x00,0x66,0x0C,0x0C,0x66,0x18,0x00,0x0E,0x0C,0x1A,0x66,
0x18,0x00,0x1C,0x0C,0x1A,0x3E,0x18,0x00,0x78,0x0C,0x1E,0x66,0x18,0x00,0x62,0x0C,
0x33,0x66,0x18,0x00,0x66,0x0C,0x33,0xE6,0x18,0x00,0x3C,0x8C,0x7B,0xCF,0x18,0x00
};

unsigned char open_pic[] = 
{
    /*--  调入了一幅图像：C:\Users\zltro\Desktop\open_pic.bmp  --*/
    /*--  宽度x高度=32x8  --*/
    0x3C,0x9F,0xDF,0x0C,0x7E,0xBF,0xDF,0x0D,0x66,0xB3,0xC1,0x0D,0x66,0xBF,0xDF,0x0F,
    0x66,0x9F,0xDF,0x0F,0x66,0x83,0xC1,0x0E,0x7E,0x83,0xDF,0x0E,0x3C,0x83,0xDF,0x0C
};

unsigned char close_pic[] = 
{
    /*--  调入了一幅图像：C:\Users\zltro\Desktop\close_pic.bmp  --*/
    /*--  宽度x高度=40x8  --*/
    0x3C,0x03,0x8F,0xE7,0x07,0x7E,0x83,0xDF,0xEC,0x07,0x66,0x83,0xD9,0x61,0x00,0x06,
    0x83,0x99,0xE3,0x07,0x06,0x83,0x19,0xEF,0x07,0x66,0x83,0x59,0x6C,0x00,0x7E,0xBF,
    0xDF,0xEC,0x07,0x3C,0x3F,0x8F,0xE7,0x07
};

//流水灯流完一次改变颜色
ws_t wsData[] = {{255,0, 0}, {0, 255, 0}, {0, 0, 250}};


//功能：把 3BYTE 的RGB数据转换成 24BYTE SPI数据
static void WS2812_send(unsigned char *rgb, unsigned char spi_index)
{
    unsigned char data[24];
    unsigned char i, bit;
    unsigned char index = 0;
        for(i = 0; i < 8; i++) // GREEN  按位发送
        {
            bit = ((rgb[GREEN_INDEX] << i) & 0x80);
            data[index] = (bit == 0x80) ? 0xfc : 0xe0;//spi发送0xfc 为ws812 1码 spi发送0xe0 为ws812 0码
            index++;
        } 
        for(i = 0; i < 8; i++) // RED
        {
            bit = ((rgb[RED_INDEX]<<i) & 0x80);
            data[index] = (bit==0x80) ? 0xfc : 0xe0;
            index++;
        }
        for(i=0; i<8; i++) // BLUE
        {
            bit = ((rgb[BLUE_INDEX]<<i) & 0x80);
            data[index] = (bit==0x80) ? 0xfc : 0xe0;
            index++;
        }
        hi_spi_host_write(spi_index, data, 24);
}
//显示整个8*8区域
void display_8x8_picture(unsigned char *ptr_pic, unsigned char color_index, unsigned char light_vol, unsigned char spi_index)
{
    uint32_t i,j;
    unsigned char rgb[3];

    for(i=0; i<8; i++)
    {
        for(j=0; j<8; j++)
        {
            if((ptr_pic[7-i]<<j)&0x80)
            {
                rgb[0] = color[color_index%7][0]&light_vol;  
                rgb[1] = color[color_index%7][1]&light_vol;  
                rgb[2] = color[color_index%7][2]&light_vol;  
            }  
            else
            {
                rgb[0] = 0;  
                rgb[1] = 0;  
                rgb[2] = 0;    
            } 
            WS2812_send(rgb, spi_index);
        }
    }   
}


//显示一个静态的8*8图片显示
void static_display_8x8_picture(unsigned char *ptr_pic, unsigned char color_index, unsigned char light_vol, unsigned char spi_index)
{
    unsigned char data[50];
    unsigned char i=0;
    unsigned int j;
    //unsigned char light=128;
    memset(data, 0, sizeof(data));
    hi_spi_host_write(spi_index, data, sizeof(data));//前50byte为低电平break
    while(keep_going)
    {

        display_8x8_picture(ptr_pic, color_index, light_vol, spi_index);    

        sleep(1);           

        
    }
}
//左移显示一张图片
/**
 * ptr_pic 显示内容的点阵指针
 * d_len 图片总共多少列
 * color_index 要显示几种颜色，7种选择
 * light_vol 亮度
 * spi_index 使用哪个SPI口显示。
**/
void left_display_picture(unsigned char *ptr_pic, unsigned int d_len, unsigned char color_index, unsigned char light_vol, unsigned char spi_index)
{
    unsigned char data[50];
    unsigned char i=0;
    unsigned int m,n,mm;
    unsigned int b_len;
    unsigned int len = 0;
    unsigned char dis_buffer[8];
    //unsigned char light=128;
    memset(data, 0, sizeof(data));
    
    hi_spi_host_write(spi_index, data, sizeof(data));//前50byte为低电平break
    b_len = d_len/8;
    while(keep_going)
    {
        len++;
        if(len >= d_len)
        {
            len = 0;
            color_index++;
        }    
        m = len/8;
        n = len%8;
        mm = m+1;
        if(mm > b_len-1)
            mm = 0;
        for(i=0; i<8; i++)
        {
            dis_buffer[i] = (ptr_pic[b_len*i+m]>>(n)) | (ptr_pic[b_len*i+mm]<<(8-n));     
        }

        display_8x8_picture(dis_buffer, color_index, light_vol, spi_index);    
        usleep(200 * 1000);           
    }
}


//点阵8x8显示（ws2812）使用SPI1的SPI0_MOSI来驱动 
void WS2812Task(void)
{
    hi_spi_deinit(HI_SPI_ID_0); /* if wake_up from deep sleep, should deinit first */
    hi_spi_cfg_basic_info spi_cfg_basic_info;
    spi_cfg_basic_info.cpha = 0;
    spi_cfg_basic_info.cpol = 0;
    spi_cfg_basic_info.data_width = HI_SPI_CFG_DATA_WIDTH_E_8BIT;
    spi_cfg_basic_info.endian = 0;
    spi_cfg_basic_info.fram_mode = 0;
    spi_cfg_basic_info.freq = 8*900000; 
    hi_spi_cfg_init_param spi_init_param = {0};
    spi_init_param.is_slave = 0;
    hi_spi_init(HI_SPI_ID_0, spi_init_param, &spi_cfg_basic_info); //基本参数配置
    hi_spi_set_loop_back_mode(HI_SPI_ID_0, 1);
    hi_io_set_func(HI_IO_NAME_GPIO_12, HI_IO_FUNC_GPIO_12_SPI0_CSN);//io配置
    hi_io_set_func(HI_IO_NAME_GPIO_10, HI_IO_FUNC_GPIO_10_SPI0_CK);
    hi_io_set_func(HI_IO_NAME_GPIO_11, HI_IO_FUNC_GPIO_11_SPI0_RXD);
    hi_io_set_func(HI_IO_NAME_GPIO_9, HI_IO_FUNC_GPIO_9_SPI0_TXD);
    hi_io_set_driver_strength(HI_IO_NAME_GPIO_6, HI_IO_DRIVER_STRENGTH_2);//驱动能力
    hi_spi_set_irq_mode(HI_SPI_ID_0, 0);
    hi_spi_set_dma_mode(HI_SPI_ID_0, 1);

    while(1)
    {
        switch(new_status)
        {
            case 0:
                keep_going = 1;
                static_display_8x8_picture(X_pic, 1, 32, WS2812_8x8_SPI0);
            break;
            case 1:
                keep_going = 1;
                static_display_8x8_picture(R_pic, 6, 32, WS2812_8x8_SPI0);
            break;
            case 2:
                keep_going = 1;
                left_display_picture(start_pic, 48, 4, 32, WS2812_8x8_SPI0);
            break;            
            case 3:
                keep_going = 1;
                left_display_picture(open_pic, 32, 4, 32, WS2812_8x8_SPI0);
            break;     
            case 4:
                keep_going = 1;
                left_display_picture(close_pic, 40, 4, 32, WS2812_8x8_SPI0);
            break;     
            default:
                keep_going = 1;
                left_display_picture(spark_pic, 48, 4, 32, WS2812_8x8_SPI0);
            break;     
        }
    }

    // static_display_8x8_picture(WS2812_8x8_SPI0);

}

// //灯带的显示任务（ws2812）使用SPI1的SPI1_MOSI来驱动 
// static void WS2812_light_line_Task(void)
// { 
//     hi_spi_deinit(HI_SPI_ID_1); /* if wake_up from deep sleep, should deinit first */
//     hi_spi_cfg_basic_info spi_cfg_basic_info;
//     spi_cfg_basic_info.cpha = 0;
//     spi_cfg_basic_info.cpol = 0;
//     spi_cfg_basic_info.data_width = HI_SPI_CFG_DATA_WIDTH_E_8BIT;
//     spi_cfg_basic_info.endian = 0;
//     spi_cfg_basic_info.fram_mode = 0;
//     spi_cfg_basic_info.freq = 8*900000; 
//     hi_spi_cfg_init_param spi_init_param = {0};
//     spi_init_param.is_slave = 0;
 
//     hi_spi_init(HI_SPI_ID_1, spi_init_param, &spi_cfg_basic_info); //基本参数配置
//     hi_spi_set_loop_back_mode(HI_SPI_ID_1, 1);
//     hi_io_set_func(HI_IO_NAME_GPIO_0, HI_IO_FUNC_GPIO_0_SPI1_CK);//io配置
//     hi_io_set_func(HI_IO_NAME_GPIO_1, HI_IO_FUNC_GPIO_1_SPI1_RXD);
//     hi_io_set_func(HI_IO_NAME_GPIO_2, HI_IO_FUNC_GPIO_2_SPI1_TXD);
//     hi_io_set_func(HI_IO_NAME_GPIO_3, HI_IO_FUNC_GPIO_3_SPI1_CSN);
//     hi_spi_set_irq_mode(HI_SPI_ID_1, 0);
//     hi_spi_set_dma_mode(HI_SPI_ID_1, 1);
//     Paoma();
// }

 
